/*
 * q.c
 *
 *  Created on: 2016-10-29
 *      Author: m
 */

#include "q.h"
#include "string.h"

void q_init(Q* q, char* buf, u32 buf_len, u32 ele_len) {
    memset(q, 0, sizeof(Q));
    memset(buf, 0, buf_len);
    q->write_pos = buf;
    q->read_pos = buf;
    q->buf_base = buf;
    q->buf_len = buf_len;
    q->ele_len = ele_len;
    q->cap_cnt = buf_len / ele_len;
}

int q_push(Q* q, void* ele) {
    if(q->count >= q->cap_cnt) return -1;
    memcpy(q->write_pos, ele, q->ele_len);
    q->write_pos += q->ele_len;
    q->count++;
    if(q->write_pos >= &q->buf_base[q->buf_len]) {
        q->write_pos = q->buf_base;
    }
    return 0;
}

int q_pop(Q* q, void* ele) {
    if(q->count <= 0) return -1;

    if(q->read_pos >= &(q->buf_base[q->buf_len])) {
        q->read_pos = q->buf_base;
    }
    memcpy(ele, q->read_pos, q->ele_len);
    q->read_pos += q->ele_len;
    q->count--;
    return 0;
}

//return the element count in q
u32 q_size(Q* q) {
    return q->count;
}
int q_front(Q* q, void* ele, u32 idx) {
    if(q->count <= 0) return -1;
    char* read_pos = q->read_pos + idx * q->ele_len;
    while(read_pos >= &(q->buf_base[q->buf_len])) {
        read_pos -= q->buf_len;
    }
    if(read_pos < q->buf_base) {
        return -1;
    }
    memcpy(ele, read_pos, q->ele_len);
    return 0;
}
int q_back(Q* q, void* ele, u32 idx) {
    return 0;
}
